package mosdi.tests;

import junit.framework.TestCase;
import mosdi.fa.CDFA;
import mosdi.fa.DFAFactory;
import mosdi.fa.FiniteMemoryTextModel;
import mosdi.fa.MarkovianTextModel;
import mosdi.paa.DAA;
import mosdi.paa.PAA;
import mosdi.paa.TextBasedPAA;
import mosdi.paa.apps.MatchCountDAA;
import mosdi.util.Alphabet;

public class PAATest extends TestCase {
	private static final String text = "CGGATCTGATTTTGCTGCGCCCAATGAAGGAAGGCGGCGGGTATCCCACGCTTTGGATCCGATACAATGGGTTAAACAGATGAATGAGAGTTTAGAATACGTTGCTCCAAAGTTCGTTCTAACCCAACAGACAGGCGCTCCGCGAACGTCTGTAAAAGAGGCATCTGCCACGCAATCGTGGAGTGCAGGCTGGTGTTGGGACCATAGTCAATCAATCTTCAGCAAGTTACTACAGGTACTCGAACGTCTG";
	// correct values as verified by simulation
	private static final double[] solution1 = {0.0,0.0,0.0,0.0153229662940584,0.0153229662940584,0.01429823291598135,0.01410388693048398,0.01393721567510691,0.01372846792966407,0.013523015525097028,0.013322978035922623,0.013125809678455811,0.012931437264040047,0.01273995221170346,0.012551308822439057,0.012365458022979434,0.012182358861521176,0.012001970953795037,0.011824254119691548,0.011649168789734217,0.011476676000867693,0.01130673736542892,0.011139315063130345,0.010974371833819491,0.01081187096911792,0.010651776304191205,0.01049405220970615,0.010338663583904473,0.010185575844790415,0.010034754922434335,0.009886167251390401,0.00973977976322656,0.009595559879165098,0.009453475502832182,0.009313495013114756,0.009175587257123212,0.009039721543258262,0.00890586763438048,0.008773995741080953,0.008644076515051632,0.008516081042553783,0.008389980837983218,0.008265747837530752,0.008143354392936574,0.008022773265337069,0.007903977619202763,0.007786941016366049,0.007671637410137307,0.007558041139508179,0.0074461269234406754,0.007335869855240829,0.007227245397015674,0.0071202293742122945,0.007014797970237742,0.0069109277211586075,0.006808595510479084,0.006707778563996365,0.006608454444732189,0.006510601047939467,0.006414196596182828,0.006319219634492016,0.006225649025587051,0.006133463945174095,0.0060426438773109655,0.005953168609841285,0.0058650182298962215,0.005778173119462863,0.005692613951018183,0.00560832168322767,0.005525277556707653,0.005443463089850367,0.005362860074710833,0.005283450572954664,0.005205216911865845,0.005128141680413655,0.005052207725377796,0.004977398147530932,0.004903696297877727,0.00483108577394959,0.004759550416154273,0.004689074304179534,0.004619641753450038,0.00455123731163673,0.004483845755217901,0.004417452086091158,0.0043520415282355795,0.004287599524423279,0.0042241117329796804,0.004161564024591747,0.00409994247916348,0.004039233382717984,0.003979423224345388,0.003920498693195984,0.0038624466755178615,0.003805254251738432,0.003748908693589148,0.003693397461272809,0.003638708200672813,0.00358482874060372,0.0035317470901025387,0.0034794514357601187,0.0034279301390920535,0.0033771717339485196,0.0033271649239624635,0.003277898580035578,0.0032293617378615046,0.003181543595485704,0.003134433510901467,0.0030880209996815198,0.003042295732644691,0.002997247533557144,0.0029528663768676293,0.002909142385476292,0.002866065828536498,0.0028236271192892243,0.002781816812929505,0.0027406256045044786,0.0027000443268425513,0.002660063948513232,0.0026206755718171703,0.0025818704308059556,0.0025436398893312474,0.0025059754391227825,0.0024688686978948443,0.002432311407480773,0.002396295431995096,0.0023608127560228774,0.0023258554828358654,0.0022914158326350705,0.002257486140819354,0.0022240588562796597,0.0021911265397185032,0.0021586818619943418,0.0021267176024904622,0.0020952266475080224,0.0020642019886828837,0.0020336367214258896,0.0020035240433862356,0.0019738572529375987,0.001944629747686676,0.0019158350230038114,0.0018874666705753817,0.0018595183769776135,0.0018319839222715219,0.0018048571786186513,0.0017781321089173163,0.001751802765459034,0.0017258632886048512,0.0017003079054812732,0.0016751309286955002,0.001650326755069689,0.0016258898643939559,0.0016018148181978478,0.0015780962585399956,0.0015547289068157028,0.0015317075625821774,0.0015090271024011674,0.0014866824786987308,0.0014646687186418905,0.0014429809230319202,0.0014216142652140205,0.0014005639900031399,0.0013798254126256983,0.0013593939176769852,0.0013392649580939934,0.0013194340541434597,0.001299896792424897,0.0012806488248883828,0.0012616858678668919,0.0012430037011229623,0.0012245981669094725,0.0012064651690443281,0.0011886006719988502,0.0011710006999996615,0.001153661336143872,0.0011365787215273637,0.001119749054385989,0.0011031685892494774,0.0010868336361078777,0.001070740559590339,0.0010548857781560548,0.0010392657632971815,0.0010238770387535666,0.0010087161797391,9.937798121795217E-4,9.790646119615166E-4,9.645673041929275E-4,9.502846624739224E-4,9.362135081789536E-4,9.2235070974935E-4,9.086931819963822E-4,8.952378854146506E-4,8.81981825505637E-4,8.68922052111274E-4,8.560556587573835E-4,8.433797820068348E-4,8.308916008222826E-4,8.185883359383408E-4,8.064672492430515E-4,7.945256431685145E-4,7.827608600905383E-4};
	private static final double[] solution2 = {0.0,0.0,0.0,0.026412679778519268,0.018134078653908748,0.018134078653908748,0.01813407865390875,0.017686054363704455,0.017348898477925322,0.01701969131081221,0.016690827245630504,0.01636958110312421,0.016054556204301934,0.0157455151248016,0.015442438759324335,0.01514519687377331,0.014853675366380114,0.014567765393013663,0.01428735875127051,0.014012349483849197,0.01374263371634311,0.013478109554869895,0.013218677068757526,0.01296423825145212,0.012714696982627328,0.012469958992144668,0.012229931824426566,0.011994524803517264,0.011763648998831283,0.011537217191557677,0.011315143841710866,0.01109734505581595,0.010883738555215936,0.010674243644989029,0.010468781183464226,0.010267273552323646,0.010069644627280395,0.009875819749320794,0.009685725696500171,0.009499290656281542,0.009316444198406708,0.00913711724828957,0.00896124206092155,0.008788752195279326,0.008619582489225132,0.008453669034890251,0.00829094915453227,0.008131361376857087,0.007974845413796693,0.007821342137733878,0.007670793559165423,0.007523142804795148,0.0073783340960487,0.007236312728001867,0.007097025048714491,0.006960418438962183,0.006826441292358153,0.006695042995857689,0.006566173910637859,0.0064397853533452835,0.006315829577704838,0.006194259756482367,0.006075029963794587,0.005958095157759486,0.0058434111634807,0.005730934656359386,0.005620623145727325,0.005512434958795078,0.0054063292249090875,0.005302265860111829,0.005200205551999138,0.005100109744869022,0.005001940625156324,0.004905661107147757,0.004811234818971898,0.00471862608885884,0.004627799931664346,0.004538722035653376,0.00445135874953802,0.004365677069764913,0.004281644628047379,0.004199229679137529,0.004118401088833742,0.0040391283222189905,0.00396138143212554,0.0038851310478217067,0.003810348363916357,0.0037370051294769984,0.0036650736373573098,0.003594526713730116,0.003525337707821828,0.0034574804818444803,0.0033909294011215648,0.0033256593244039194,0.0032616455943720287,0.0031988640283211354,0.0031372909090256473,0.0030769029757793972,0.0030176774156083584,0.002959591854652499,0.002902624349713531,0.002846753379965342,0.0027919578388239967,0.0027382170259742217,0.0026855106395493717,0.0026338187684619156,0.0025831218848815546,0.0025334008368581187,0.002484636841086463,0.00243681147581063,0.002389906673864594,0.0023439047158469602,0.002298788223427041,0.0022545401527797803,0.002211143788147041,0.0021685827355228354,0.0021268409164600967,0.002085902561996668,0.0020457522066981986,0.0020063746828157146,0.0019677551145556352,0.001929878912460097,0.0018927317678954318,0.0018562996476467475,0.0018205687886165458,0.0017855256926253855,0.0017511571213126244,0.0017174500911353162,0.001684391868463369,0.001651969964769114,0.0016201721319094675,0.0015889863574989052,0.001558400860371497,0.0015284040861302975,0.0014989847027823894,0.0014701315964579633,0.0014418338672117846,0.001414080824905482,0.0013868619851690948,0.0013601670654403526,0.0013339859810801939,0.0013083088415630547,0.001283125946740488,0.0012584277831767016,0.0012342050205546337,0.0012104485081512024,0.0011871492713804055,0.0011642985084029556,0.0011418875868011774,0.001119908040317907,0.0010983515656581631,0.0010772100193523798,0.0010564754146800176,0.0010361399186523906,0.00101619584905357,9.96635671538243E-4,9.774519967854372E-4,9.58637577707028E-4,9.401853067099791E-4,9.220882130112824E-4,9.043394600045767E-4,8.869323426774603E-4,8.698602850785108E-4,8.53116837833066E-4,8.366956757068176E-4,8.205905952163059E-4,8.047955122854046E-4,7.893044599469188E-4,7.741115860884199E-4,7.592111512414729E-4,7.445975264134146E-4,7.302651909608695E-4,7.162087305041945E-4,7.024228348820698E-4,6.889022961454586E-4,6.756420065901812E-4,6.626369568273582E-4,6.498822338909965E-4,6.373730193819978E-4,6.251045876478958E-4,6.130723039976271E-4,6.012716229506689E-4,5.896980865198743E-4,5.783473225273623E-4,5.672150429528245E-4,5.562970423136229E-4,5.455891960760692E-4,5.350874590972855E-4,5.24787864097054E-4,5.14686520159084E-4,5.047796112611253E-4,4.950633948333755E-4,4.8553420034463615E-4,4.761884279156811E-4,4.6702254695931816E-4,4.580330948466254E-4,4.492166755988605E-4,4.4056995860455053E-4,4.320896773612732E-4,4.237726282416589E-4,4.1561566928314365E-4};

	private void waitingTimeForValueRun(CDFA cdfa, FiniteMemoryTextModel textModel, double[] solution) {
		DAA daa = new MatchCountDAA(cdfa, 1);
		PAA paa = new TextBasedPAA(daa, textModel);
		double[] wtDist = paa.waitingTimeForValue(200, 1);
		for (int i=0; i<=200; ++i) {
			if (solution[i] == 0.0) {
				assertTrue(wtDist[i] == 0.0);
			} else {
				assertEquals(1.0,solution[i]/wtDist[i],1e-10);
			}
			// System.out.print(wtDist[i]+",");
		}
		// System.out.println();
	}
	
	public void testWaitingTimeForValue() {
		Alphabet dnaAlphabet = Alphabet.getDnaAlphabet();
		FiniteMemoryTextModel textModel = new MarkovianTextModel(1, dnaAlphabet.size(), dnaAlphabet.buildIndexArray(text));
		waitingTimeForValueRun(DFAFactory.buildFromIupacPattern("CGC"), textModel, solution1);
		waitingTimeForValueRun(DFAFactory.buildFromIupacPattern("AAA"), textModel, solution2);
	}
}
